﻿namespace Text2Rss.Web
{
	#region Using Directives
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Reflection;
	using System.Web;
	using System.Web.Mvc;
	using System.Web.Routing;
	using Castle.MicroKernel.Registration;
	using Castle.Windsor;
	using NHibernate;
	using NHibernate.ByteCode.Castle;
	using NHibernate.Cfg;
	using NHibernate.Cfg.Loquacious;
	using NHibernate.Connection;
	using NHibernate.Dialect;
	using NHibernate.Driver;
	using Text2Rss.Web.Code;
	#endregion

	//// Note: For instructions on enabling IIS6 or IIS7 classic mode,
	//// visit http://go.microsoft.com/?LinkId=9394801

	/// <summary>
	/// Main Mvc Application
	/// </summary>
	public class MvcApplication : System.Web.HttpApplication
	{
		/// <summary>
		/// global Controllers container
		/// </summary>
		private static IWindsorContainer container;

		/// <summary>
		/// Registers global filtrs
		/// </summary>
		/// <param name="filters">Global Filters Collection</param>
		public static void RegisterGlobalFilters(GlobalFilterCollection filters)
		{
			filters.Add(new HandleErrorAttribute());
		}

		/// <summary>
		/// Registers main routes
		/// </summary>
		/// <param name="routes">Route collection</param>
		public static void RegisterRoutes(RouteCollection routes)
		{
			routes.IgnoreRoute("themes/{*pathInfo}");
			routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
			routes.IgnoreRoute("favicon.ico");
			routes.IgnoreRoute("{*allgif}", new { allgif = @".*\.gif(/.*)?" });
			routes.IgnoreRoute("{*allpng}", new { allgif = @".*\.png(/.*)?" });
			routes.IgnoreRoute("{*allcss}", new { allcss = @".*\.css(/.*)?" });
			routes.IgnoreRoute("{*allhtml}", new { allhtml = @".*\.html(/.*)?" });
			routes.IgnoreRoute("{*allpsd}", new { allpsd = @".*\.psd(/.*)?" });
			routes.IgnoreRoute("{*allswf}", new { allswf = @".*\.swf(/.*)?" });
			routes.IgnoreRoute("{*alljs}", new { alljs = @".*\.js(/.*)?" });

			routes.MapRoute(
				"Default", // Route name
				"{controller}/{action}/{id}", // URL with parameters
				new { controller = "Home", action = "Index", id = UrlParameter.Optional }); // Parameter defaults
		}

		/// <summary>
		/// Регистрируем в контейнере фабрику контроллеров
		/// </summary>
		/// <param name="windsorContainer">Контейнер</param>
		private static void RegisterControllerFactory(IWindsorContainer windsorContainer)
		{
			windsorContainer.Register(Component
				.For<IWindsorContainer>()
				.Instance(windsorContainer));

			windsorContainer.Register(
				Component
					.For<IControllerFactory>()
					.ImplementedBy<WindsorControllerFactory>()
					.DependsOn(new
					{
						controllersAssemblies = new[]
						{
							Assembly.GetExecutingAssembly()
						}
					})
					.LifeStyle.Singleton);

			ControllerBuilder.Current.SetControllerFactory(windsorContainer.Resolve<IControllerFactory>());
		}

		/// <summary>
		/// Регистрируем в контейнере фабрику сессий
		/// </summary>
		/// <param name="windsorContainer">Контейнер</param>
		private static void RegisterSessionFactory(IWindsorContainer windsorContainer)
		{
			ISessionFactory factory = new Configuration()
					.CurrentSessionContext<NHibernate.Context.ManagedWebSessionContext>()
					.Proxy(x => x.ProxyFactoryFactory<ProxyFactoryFactory>())
					.DataBaseIntegration(x =>
					{
						x.ConnectionProvider<DriverConnectionProvider>();
						x.Driver<SqlClientDriver>();
						x.ConnectionStringName = "main";
						x.ConnectionReleaseMode = ConnectionReleaseMode.OnClose;
						x.Dialect<MsSql2008Dialect>();
					})
					.AddAssembly("Text2Rss.Web")
					.BuildSessionFactory();

			windsorContainer.Register(Component
								.For<ISessionFactory>()
								.Instance(factory));
		}

		protected void Application_Start()
		{
			Log.Initialize(Server.MapPath("~/log4net.config"));
			AreaRegistration.RegisterAllAreas();
			RegisterGlobalFilters(GlobalFilters.Filters);

			container = new WindsorContainer();
			RegisterControllerFactory(container);
			RegisterSessionFactory(container);

			RegisterRoutes(RouteTable.Routes);
		}

		protected void Application_Error(object sender, EventArgs e)
		{
			Exception ex = Server.GetLastError();
			Log.Logger.Fatal("Неизвестная ошибка", ex);
		}
	}
}
